﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using DataAccess.Entities;
using Zeenck.DataAccess;
using Zeenck.Models;
using Zeenck.DataAccess.Repositories;

namespace Zeenck.Controllers
{
    public class RegistrationController : Controller
    {
        [HttpGet]
        public ActionResult Begin()
        {
            if (User.Identity.IsAuthenticated)
            {
                return Redirect(Url.Home());
            }

            return View("LoginAndRegistration/LoginAndRegistration", new LoginAndRegistration());
        }

        [HttpPost]
        public ActionResult Submit(Registration model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                Account account = AccountModule.CreateAccount(model.FirstName, model.LastName, model.ClientUserName, model.EmailAddress, model.NewPassword, Url);
                if(account != default(Account))
                {
                    MembershipCreateStatus createStatus;
                    Membership.CreateUser(model.ClientUserName, model.NewPassword, model.EmailAddress, null, null, true, null, out createStatus);

                    if (createStatus == MembershipCreateStatus.Success)
                    {
                        String title = Configuration.Zeenck.Info.Registration.CompleteTitle;
                        String message = String.Format(Configuration.Zeenck.Info.Registration.CompleteThankYou,
                                                       model.FirstName, model.LastName);
                        message += " ";
                        message += String.Format(Configuration.Zeenck.Info.Registration.CompleteCallToAction,
                                                 model.EmailAddress);
                        var applicationMessage = new ApplicationMessage(title, message);
                        return View("General/ApplicationMessage", applicationMessage);
                    }

                    IRepository<Account> repo = new AccountRepository();
                    repo.Delete(account.Id);
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }

                ModelState.AddModelError("", "There was an error in your registration");
            }

            var parentModel = new LoginAndRegistration
            {
                Registration = model
            };

            return View("LoginAndRegistration/LoginAndRegistration", parentModel);
        }

        [Authorize]
        [HttpGet]
        public ActionResult CompleteRegistration(int profileId)
        {
            Profile profile = ProfileModule.GetProfile(profileId);
            ZeenckProfile model = SetProfileContent(profile);
            return View("CompleteRegistration", model);
        }

        [Authorize]
        [HttpPost]
        public ActionResult CompleteRegistration(ZeenckProfile profile, FormCollection form)
        {
            if (ModelState.IsValid)
            {
                profile.Personal.Birthday = Convert.ToDateTime(form["Birthday"]);
                profile.Personal.Gender = form["Gender"];
                profile.Personal.InterestedIn = form["InterestedIn"];
                profile.Personal.RelationshipStatus = form["RelationshipStatus"];
                profile.Basic.Passion = form["Passion"];
                profile.Portfolio.Url = form["Url"];
                profile.Portfolio.Bio = form["Bio"];

                string selectedValues = form["Interests"];
                profile.Basic.Interests = selectedValues.Split(',');

                ProfileModule.UpdateProfile(profile);
                return Redirect(Url.Home());
            }

            Profile p = ProfileModule.GetProfile(profile.Id);
            SetProfileContent(p);
            return View(profile);
        }

        private ZeenckProfile SetProfileContent(Profile profile)
        {
            ZeenckProfile model = null;
            try
            {
                IRepository<Account> accountRepo = new AccountRepository();
                Account account = accountRepo.GetById(profile.Account.Id);
                ViewBag.Name = account.FirstName;

                IRepository<Gender> genderRepo = new GenderRepository();
                IEnumerable<SelectListItem> genders = genderRepo.GetAll().ToList()
                    .Select(
                        i => new SelectListItem
                                 {
                                     Value = i.Type,
                                     Text = i.Type
                                 }
                    );

                IRepository<RelationshipStatus> statusRepo = new RelationshipStatusRepository();
                IEnumerable<SelectListItem> status = statusRepo.GetAll().ToList()
                    .Select(
                        i => new SelectListItem
                                 {
                                     Value = i.Status,
                                     Text = i.Status
                                 }
                    );

                IRepository<Interest> interestRepo = new InterestRepository();
                IEnumerable<SelectListItem> interests = interestRepo.GetAll().ToList()
                    .Select(
                        i => new SelectListItem
                                 {
                                     Value = i.Name,
                                     Text = i.Name
                                 }
                    );

                ViewBag.Gender = genders;
                ViewBag.RelationshipStatus = status;
                ViewBag.InterestedIn = genders;
                ViewBag.Interests = interests;

                var basic = new Basic
                                {
                                    FirstName = account.FirstName,
                                    LastName = account.LastName,
                                    Email = account.Email,
                                    UserName = account.UserName,
                                    Passion = (profile.Passion == null) ? null : profile.Passion.Name,
                                    Status = profile.Status,
                                    Picture = profile.Picture
                                };

                var personal = new Personal
                                   {
                                       Birthday = profile.Birthday,
                                       Gender = (profile.Gender == null) ? null : profile.Gender.Type,
                                       RelationshipStatus = (profile.RelationshipStatus == null) ? null : profile.RelationshipStatus.Status
                                   };

                var portfolio = new Portfolio
                                    {
                                        Bio = profile.Bio,
                                        Url = profile.Url
                                    };

                model = new ZeenckProfile
                                {
                                    Id = profile.Id,
                                    Basic = basic,
                                    Personal = personal,
                                    Portfolio = portfolio,
                                };

                return model;
            } catch (Exception e)
            {
                ModelState.AddModelError("", e);    
            }

            return model;
        }

        [HttpPost]
        public JsonResult FindInterests(string searchText, int maxResults)
        {
            IRepository<Interest> repository = new InterestRepository();
            var result = repository.Find(searchText, maxResults);
            return Json(result);
        }

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion
    }
}
